package cn.xzc.job.cocurrent;


import java.util.concurrent.*;

/**
 * 异步执行和回调通知
 *
 * @author xzc
 * 当前时间 2024-02-12 21:30:00
 */
public class JobExecutorAdapter implements AsyncListenableJobExecutor {
    private final Executor concurrentExecutor;
    
    private RunnableDecorator runnableDecorator;

    public JobExecutorAdapter(Executor concurrentExecutor) {
        this.concurrentExecutor = concurrentExecutor;
    }


    public final void setRunnableDecorator(RunnableDecorator runnableDecorator) {
        this.runnableDecorator = runnableDecorator;
    }

    @Override
    public void execute(Runnable job) {
        try {
            this.doExecute(this.concurrentExecutor, this.runnableDecorator, job);
        } catch (RejectedExecutionException var3) {
            throw new RejectedExecutionException("Executor [" + this.concurrentExecutor + "] did not accept Job: " + job, var3);
        }
    }


    @Override
    public Future<?> submit(Runnable job) {
        try {
            if (this.runnableDecorator == null && this.concurrentExecutor instanceof ExecutorService) {
                return ((ExecutorService) this.concurrentExecutor).submit(job);
            } else {
                FutureTask<Object> future = new FutureTask(job, null);
                this.doExecute(this.concurrentExecutor, this.runnableDecorator, future);
                return future;
            }
        } catch (RejectedExecutionException var3) {
            throw new RejectedExecutionException("Executor [" + this.concurrentExecutor + "] did not accept task: " + job, var3);
        }
    }

    @Override
    public <T> Future<T> submit(Callable<T> task) {
        try {
            if (this.runnableDecorator == null && this.concurrentExecutor instanceof ExecutorService) {
                return ((ExecutorService) this.concurrentExecutor).submit(task);
            } else {
                FutureTask<T> future = new FutureTask(task);
                this.doExecute(this.concurrentExecutor, this.runnableDecorator, future);
                return future;
            }
        } catch (RejectedExecutionException var3) {
            throw new RejectedExecutionException("Executor [" + this.concurrentExecutor + "] did not accept task: " + task, var3);
        }
    }

    @Override
    public ListenableFuture<?> submitListenable(Runnable task) {
        try {
            ListenableFutureTask<Object> future = new ListenableFutureTask(task, null);
            this.doExecute(this.concurrentExecutor, this.runnableDecorator, future);
            return future;
        } catch (RejectedExecutionException var3) {
            throw new RejectedExecutionException("Executor [" + this.concurrentExecutor + "] did not accept task: " + task, var3);
        }
    }

    @Override
    public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
        try {
            ListenableFutureTask<T> future = new ListenableFutureTask(task);
            this.doExecute(this.concurrentExecutor, this.runnableDecorator, future);
            return future;
        } catch (RejectedExecutionException var3) {
            throw new RejectedExecutionException("Executor [" + this.concurrentExecutor + "] did not accept task: " + task, var3);
        }
    }

    protected void doExecute(Executor concurrentExecutor, 
                             RunnableDecorator runnableDecorator, Runnable runnable) throws RejectedExecutionException {
        concurrentExecutor.execute(runnableDecorator != null ? runnableDecorator.decorate(runnable) : runnable);
    }
}